/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.editors.entity;

import cn.easyplatform.entities.beans.api.ApiBean;
import cn.easyplatform.entities.beans.api.Input;
import cn.easyplatform.entities.beans.api.Output;
import cn.easyplatform.entities.beans.table.TableField;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.identity.GetRolesCmd;
import cn.easyplatform.studio.cmd.identity.GetUsersCmd;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.HttpUtils;
import cn.easyplatform.studio.utils.WebUtils;
import cn.easyplatform.studio.vos.RoleVo;
import cn.easyplatform.studio.vos.UserVo;
import cn.easyplatform.studio.web.editors.AbstractEntityEditor;
import cn.easyplatform.studio.web.editors.BandboxCallback;
import cn.easyplatform.studio.web.editors.Editor;
import cn.easyplatform.studio.web.editors.EditorCallback;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import cn.easyplatform.studio.web.views.impl.AbstractView;
import cn.easyplatform.type.FieldType;
import cn.easyplatform.type.ScopeType;
import cn.easyplatform.web.ext.cmez.CMeditor;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.DropEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 潘凌
 */
public class ApiEntityEditor extends AbstractEntityEditor<ApiBean> {

    private Tabbox tabbox;

    private Textbox entityName;

    private Textbox entityDesp;

    private Bandbox entityDb;

    private Bandbox refId;

    private Checkbox anonymity;

    private Listbox inputs;

    private Listbox outputs;

    private Listbox sourceRoles;

    private Listbox targetRoles;

    private Listbox sourceUsers;

    private Listbox targetUsers;

    private List<RoleVo> allRoles;

    private List<UserVo> allUsers;

    /**
     * @param workbench
     * @param entity
     * @param code
     */
    public ApiEntityEditor(WorkbenchController workbench, ApiBean entity,
                           char code) {
        super(workbench, entity, code);
    }

    @Override
    public void create(Object... args) {
        super.create(args);
        Tabpanel tabpanel = new Tabpanel();
        Idspace is = new Idspace();
        is.setHflex("1");
        is.setVflex("1");
        is.setParent(tabpanel);
        Executions.createComponents("~./include/editor/entity/api.zul", is,
                null);
        String theme = Contexts.getUser().getEditorTheme();
        for (Component comp : is.getFellows()) {
            if (comp.getId().equals("api_textbox_name")) {
                entityName = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                entityName.setValue(entity.getName());
            } else if (comp.getId().equals("api_textbox_desp")) {
                entityDesp = (Textbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                entityDesp.setValue(entity.getDescription());
            } else if (comp.getId().equals("api_bandbox_db")) {
                entityDb = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                entityDb.setValue(entity.getSubType());
            } else if (comp.getId().equals("api_bandbox_refId")) {
                refId = (Bandbox) comp;
                comp.addEventListener(Events.ON_CHANGE, this);
                comp.addEventListener(Events.ON_OPEN, this);
                refId.setValue(entity.getRefId());
            } else if (comp.getId().equals("api_button_go")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_button_apiTest")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_listbox_inputs")) {
                inputs = (Listbox) comp;
                inputs.getPagingChild().setMold("os");
                inputs.addEventListener(Events.ON_DROP, this);
            } else if (comp.getId().equals("api_a_addInput")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_a_insertInput")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_a_deleteInput")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_a_moveUpInput")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_a_moveDownInput")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_listbox_outputs")) {
                outputs = (Listbox) comp;
                outputs.getPagingChild().setMold("os");
                outputs.addEventListener(Events.ON_DROP, this);
            } else if (comp.getId().equals("api_a_addOutput")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_a_insertOutput")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_a_deleteOutput")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_a_moveUpOutput")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_a_moveDownOutput")) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_cmeditor_source")) {
                source = (CMeditor) comp;
                source.setTheme(theme);
            } else if (comp.getId().equals("api_tabbox_main")) {
                tabbox = (Tabbox) comp;
                tabbox.addEventListener(Events.ON_SELECT, this);
            } else if (comp.getId().equals("api_listbox_sourceRoles")) {
                sourceRoles = (Listbox) comp;
            } else if (comp.getId().equals("api_listbox_targetRoles")) {
                targetRoles = (Listbox) comp;
                comp.addEventListener(Events.ON_DROP, this);
            } else if (comp.getId().equals("api_listbox_sourceUsers")) {
                sourceUsers = (Listbox) comp;
            } else if (comp.getId().equals("api_listbox_targetUsers")) {
                targetUsers = (Listbox) comp;
                comp.addEventListener(Events.ON_DROP, this);
            } else if (comp instanceof Image) {
                comp.addEventListener(Events.ON_CLICK, this);
            } else if (comp.getId().equals("api_label_name")) {
                Label nameLabel = (Label) comp;
                nameLabel.setValue(Labels.getLabel("entity.id") + "：" + entity.getId() + " " +
                        Labels.getLabel("entity.name") + "：" + entity.getName());
            } else if (comp.getId().equals("api_checkbox_anonymity")) {
                anonymity = (Checkbox) comp;
                anonymity.addEventListener(Events.ON_CHECK, this);
                anonymity.setChecked(entity.isAnonymous());
            }
        }
        if (entity.getInputs() != null) {
            for (Input input : entity.getInputs())
                createInput(input, -1);
        }
        if (entity.getOutputs() != null) {
            for (Output output : entity.getOutputs())
                createOutput(output, -1);
        }
        redraw();
        workbench.addEditor(tab, tabpanel);
    }

    @Override
    protected void redraw() {
        allUsers = StudioApp.execute(new GetUsersCmd());
        for (UserVo user : allUsers) {
            Listitem row = new Listitem();
            row.setValue(user);
            row.appendChild(new Listcell(user.getId()));
            row.appendChild(new Listcell(user.getName()));
            sourceUsers.appendChild(row);
        }
        allRoles = StudioApp.execute(new GetRolesCmd());
        for (RoleVo role : allRoles) {
            Listitem row = new Listitem();
            row.setValue(role);
            row.appendChild(new Listcell(role.getId()));
            row.appendChild(new Listcell(role.getName()));
            row.appendChild(new Listcell(role.getDesp()));
            sourceRoles.appendChild(row);
        }
        if (!Strings.isBlank(entity.getRunAsUsers())) {
            String[] usersArray = entity.getRunAsUsers().split(",");
            for (String userStr : usersArray) {
                for (UserVo user : allUsers) {
                    if (user.getId().equals(userStr)) {
                        targetUsers.appendChild(createUser(user));
                        break;
                    }
                }
            }
        }
        if (!Strings.isBlank(entity.getRunAsRoles())) {
            String[] rolesArray = entity.getRunAsRoles().split(",");
            for (String roleStr : rolesArray) {
                for (RoleVo role : allRoles) {
                    if (role.getId().equals(roleStr)) {
                        targetRoles.appendChild(createRole(role));
                        break;
                    }
                }
            }
        }
    }

    private Listitem createRole(RoleVo vo) {
        Listitem li = new Listitem();
        li.setValue(vo);
        li.appendChild(new Listcell(vo.getId()));
        li.appendChild(new Listcell(vo.getName()));
        li.appendChild(new Listcell(vo.getDesp()));
        return li;
    }

    private Listitem createUser(UserVo vo) {
        Listitem li = new Listitem();
        li.setValue(vo);
        li.appendChild(new Listcell(vo.getId()));
        li.appendChild(new Listcell(vo.getName()));
        return li;
    }

    private void setRunAsRoles() {
        String rolesStr = "";
        List<Listitem> items = targetRoles.getItems();
        for (int i = 0; i < items.size(); i++) {
            RoleVo vo = items.get(i).getValue();
            if (!rolesStr.contains(vo.getId())) {
                rolesStr += vo.getId() + ",";
            }
        }
        if (!Strings.isBlank(rolesStr))
            rolesStr = rolesStr.substring(0, rolesStr.length() - 1);
        entity.setRunAsRoles(rolesStr);
    }

    private void setRunAsUsers() {
        String usersStr = "";
        List<Listitem> items = targetUsers.getItems();
        for (int i = 0; i < items.size(); i++) {
            UserVo vo = items.get(i).getValue();
            if (!usersStr.contains(vo.getId())) {
                usersStr += vo.getId() + ",";
            }
        }
        if (!Strings.isBlank(usersStr))
            usersStr = usersStr.substring(0, usersStr.length() - 1);
        entity.setRunAsUsers(usersStr);
    }

    @Override
    protected boolean validate() {
        if (Strings.isBlank(entity.getName())) {
            WebUtils.notEmpty(Labels.getLabel("entity.name"));
            return false;
        }
        if (Strings.isBlank(entity.getRefId())) {
            WebUtils.notEmpty(Labels.getLabel("navi.entity"));
            return false;
        }
        /*if (entity.getInputs() == null || entity.getInputs().isEmpty()) {
            WebUtils.showError(Labels.getLabel("entity.table.field.set"));
            return false;
        }*/
        if (entity.getInputs() != null && !entity.getInputs().isEmpty()) {
            for (Input input : entity.getInputs()) {
                if (Strings.isBlank(input.getName())) {
                    WebUtils.showError(Labels
                            .getLabel("entity.table.field.name.not.empty"));
                    return false;
                }
                if (Strings.isBlank(input.getDesp())) {
                    WebUtils.showError(Labels
                            .getLabel("entity.table.field.desp.not.empty"));
                    return false;
                }
            }
        }
        if (entity.getOutputs() != null && !entity.getOutputs().isEmpty()) {
            for (Output output : entity.getOutputs()) {
                if (Strings.isBlank(output.getName())) {
                    WebUtils.showError(Labels
                            .getLabel("entity.table.field.name.not.empty"));
                    return false;
                }
                if (Strings.isBlank(output.getDesp())) {
                    WebUtils.showError(Labels
                            .getLabel("entity.table.field.desp.not.empty"));
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 不实现
     */
    @Override
    protected void refreshSource() {
        if (tabbox.getSelectedIndex() == 3)
            super.refreshSource();
    }

    /**
     * 生成栏位
     *
     * @param
     */
    private Listitem createInput(Input input, int pos) {
        Listitem row = new Listitem();
        row.setValue(input);
        row.appendChild(new Listcell());
        // name
        Listcell cell = new Listcell();
        Textbox name = new Textbox(input.getName());
        name.setHflex("1");
        name.setParent(cell);
        cell.setParent(row);
        // type
        cell = new Listcell();
        Combobox type = WebUtils.createFieldTypeBox();
        type.setValue(input.getType().name());
        type.setHflex("1");
        type.setParent(cell);
        cell.setParent(row);
        // scope
        cell = new Listcell();
        Combobox scope = WebUtils.createScopeTypeBox();
        scope.setValue(input.getScope().name());
        scope.setHflex("1");
        scope.setParent(cell);
        cell.setParent(row);
        // share
        cell = new Listcell();
        Combobox share = new Combobox();
        Comboitem ci = new Comboitem(
                Labels.getLabel("entity.task.variables.share.0"));
        ci.setValue(0);
        ci.setParent(share);
        ci = new Comboitem(Labels.getLabel("entity.task.variables.share.1"));
        ci.setValue(1);
        ci.setParent(share);
        share.setSelectedIndex(0);
        share.setValue(input.getShareModel() == 0 ? Labels.getLabel("entity.task.variables.share.0") : Labels.getLabel("entity.task.variables.share.1"));
        share.setHflex("1");
        share.setParent(cell);
        cell.setParent(row);
        // length
        cell = new Listcell();
        Intbox length = new Intbox(input.getLength());
        length.setConstraint("no negative,no empty");
        length.setHflex("1");
        length.setParent(cell);
        cell.setParent(row);
        // decimal
        cell = new Listcell();
        Intbox decimal = new Intbox(input.getDecimal());
        decimal.setConstraint("no negative,no empty");
        decimal.setHflex("1");
        decimal.setParent(cell);
        cell.setParent(row);
        // not null
        cell = new Listcell();
        Checkbox notnull = new Checkbox();
        notnull.setMold("switch");
        notnull.setChecked(input.isRequired());
        notnull.setParent(cell);
        cell.setParent(row);
        // desp
        cell = new Listcell();
        Textbox desp = new Textbox(input.getDesp());
        desp.setHflex("1");
        desp.setParent(cell);
        cell.setParent(row);
        // value
        cell = new Listcell();
        Textbox value = new Textbox(input.getValue());
        value.setHflex("1");
        value.setParent(cell);
        cell.setParent(row);
        // acc
        cell = new Listcell();
        Textbox acc = new Textbox(input.getAcc());
        acc.setHflex("1");
        acc.setParent(cell);
        cell.setParent(row);
        if (pos >= 0) {
            inputs.getItems().add(pos, row);
        } else
            row.setParent(inputs);
        new InputObject(name, type, scope, share, length, decimal, desp, notnull, value, acc);
        return row;
    }

    /**
     * 生成栏位
     *
     * @param
     */
    private Listitem createOutput(Output output, int pos) {
        Listitem row = new Listitem();
        row.setValue(output);
        row.appendChild(new Listcell());
        // name
        Listcell cell = new Listcell();
        Textbox name = new Textbox(output.getName());
        name.setHflex("1");
        name.setParent(cell);
        cell.setParent(row);
        // not null
        cell = new Listcell();
        Checkbox notnull = new Checkbox();
        notnull.setMold("switch");
        notnull.setChecked(output.isRequired());
        notnull.setParent(cell);
        cell.setParent(row);
        // desp
        cell = new Listcell();
        Textbox desp = new Textbox(output.getDesp());
        desp.setHflex("1");
        desp.setParent(cell);
        cell.setParent(row);
        if (pos >= 0) {
            outputs.getItems().add(pos, row);
        } else
            row.setParent(outputs);
        new OutputObject(name, desp, notnull);
        return row;
    }


    @Override
    protected void dispatch(Event evt) {
        if (evt.getName().equals(Events.ON_CHANGE)
                || evt.getName().equals(Events.ON_CHECK)
                || evt.getName().equals(Events.ON_CHANGING)) {
            Component c = evt.getTarget();
            if (c == entityName)
                entity.setName(entityName.getValue());
            else if (c == entityDesp)
                entity.setDescription(entityDesp.getValue());
            else if (c == entityDb)
                entity.setSubType(entityDb.getValue());
            else if (c == refId)
                entity.setRefId(refId.getValue());
            else if (c == anonymity)
                entity.setAnonymous(anonymity.isChecked());
            setDirty();
        } else if (evt.getName().equals(Events.ON_CLICK)) {
            String id = evt.getTarget().getId();
            if ("api_a_addInput".equals(id)) {
                Input input = new Input();
                input.setType(FieldType.VARCHAR);
                if (entity.getInputs() == null)
                    entity.setInputs(new ArrayList<Input>());
                entity.getInputs().add(input);
                Listitem row = createInput(input, -1);
                setDirty();
                inputs.setActivePage(row);
            } else if ("api_a_insertInput".equals(id)) {
                int pos = inputs.getSelectedIndex();
                Input input = new Input();
                input.setType(FieldType.VARCHAR);
                if (entity.getInputs() == null)
                    entity.setInputs(new ArrayList<Input>());
                if (pos >= 0) {
                    pos++;
                    entity.getInputs().add(pos, input);
                } else
                    entity.getInputs().add(input);
                createInput(input, pos);
                setDirty();
            } else if ("api_a_deleteInput".equals(id)) {
                if (inputs.getSelectedItem() != null)
                    WebUtils.showConfirm(Labels.getLabel("button.delete"), this);
            } else if ("api_a_moveUpInput".equals(id)) {
                if (inputs.getSelectedItem() != null)
                    moveInput(false);
            } else if ("api_a_moveDownInput".equals(id)) {
                if (inputs.getSelectedItem() != null)
                    moveInput(true);
            } else if ("api_a_addOutput".equals(id)) {
                Output output = new Output();
                if (entity.getOutputs() == null)
                    entity.setOutputs(new ArrayList<Output>());
                entity.getOutputs().add(output);
                Listitem row = createOutput(output, -1);
                setDirty();
                outputs.setActivePage(row);
            } else if ("api_a_insertOutput".equals(id)) {
                int pos = outputs.getSelectedIndex();
                Output output = new Output();
                if (entity.getOutputs() == null)
                    entity.setOutputs(new ArrayList<Output>());
                if (pos >= 0) {
                    pos++;
                    entity.getOutputs().add(pos, output);
                } else
                    entity.getOutputs().add(output);
                createOutput(output, pos);
                setDirty();
            } else if ("api_a_deleteOutput".equals(id)) {
                if (outputs.getSelectedItem() != null)
                    WebUtils.showConfirm(Labels.getLabel("button.delete"), this);
            } else if ("api_a_moveUpOutput".equals(id)) {
                if (outputs.getSelectedItem() != null)
                    moveOutput(false);
            } else if ("api_a_moveDownOutput".equals(id)) {
                if (outputs.getSelectedItem() != null)
                    moveOutput(true);
            } else if ("api_button_go".equals(id)){
                if (!Strings.isBlank(refId.getValue()))
                    openEditor(evt.getTarget(), refId.getValue());
            } else if ("api_button_apiTest".equals(id)){
                if (tab.getLabel().contains("*")){
                    WebUtils.showInfo(Labels.getLabel("entity.api.preSave"));
                    return;
                }
                AbstractView.createApiTestView(new EditorCallback<ApiBean>() {
                    @Override
                    public ApiBean getValue() {
                        return entity;
                    }

                    @Override
                    public void setValue(ApiBean value) {

                    }

                    @Override
                    public String getTitle() {
                        return Labels.getLabel("entity.api.apitest");
                    }

                    @Override
                    public Page getPage() {
                        return entityName.getPage();
                    }

                    @Override
                    public Editor getEditor() {
                        return null;
                    }
                },"simple").doHighlighted();
            }
        } else if (evt.getName().equals(Events.ON_OK)) {// 删除栏位
            if (tabbox.getSelectedIndex() == 0) {
                Input input = inputs.getSelectedItem().getValue();
                entity.getInputs().remove(input);
                inputs.getSelectedItem().detach();
            } else if (tabbox.getSelectedIndex() == 1) {
                Output output = outputs.getSelectedItem().getValue();
                entity.getOutputs().remove(output);
                outputs.getSelectedItem().detach();
            }
            setDirty();
        } else if (evt.getName().equals(Events.ON_SELECT)
                && evt.getTarget() instanceof Tab) {
            refreshSource();
        } else if (evt.getTarget() == entityDb) {
            AbstractView.createDatasourceView(
                    new BandboxCallback(entityDb, Labels
                            .getLabel("entity.table.db")), evt.getTarget()).doOverlapped();
        } else if (evt.getTarget() == refId) {
            AbstractView.createApiRefIdView(
                    new BandboxCallback(refId, Labels
                            .getLabel("navi.entity")), refId).doOverlapped();
        }
        /*------------------------拖拽部分--------------------------*/
        if (evt.getName().equals(Events.ON_DROP)) {
            DropEvent de = (DropEvent) evt;
            if ("api_listbox_inputs".equals(evt.getTarget().getId())){
                Row dragRow = (Row) de.getDragged();
                TableField field = dragRow.getValue();
                Input input = new Input();
                input.setType(field.getType());
                input.setName(field.getName());
                input.setDesp(field.getDescription());
                if (entity.getInputs() == null)
                    entity.setInputs(new ArrayList<Input>());
                entity.getInputs().add(input);
                Listitem row = createInput(input, -1);
                setDirty();
                inputs.setActivePage(row);
            }
            if ("api_listbox_outputs".equals(evt.getTarget().getId())){
                Row dragRow = (Row) de.getDragged();
                TableField field = dragRow.getValue();
                Output output = new Output();
                output.setName(field.getName());
                output.setDesp(field.getDescription());
                if (entity.getOutputs() == null)
                    entity.setOutputs(new ArrayList<Output>());
                entity.getOutputs().add(output);
                Listitem row = createOutput(output, -1);
                setDirty();
                outputs.setActivePage(row);
            }
        }
        /*------------------------拖拽部分--------------------------*/
        /*-------------------------------关于授权的----------------------------------*/
        if (evt.getTarget() instanceof Image) {
            if (evt.getTarget().getId().equals("api_image_role_chooseAll")) {
                List<Listitem> items = sourceRoles.getItems();
                for (Listitem ti : items) {
                    RoleVo vo = ti.getValue();
                    targetRoles.appendChild(createRole(vo));
                }
                setRunAsRoles();
            } else if (evt.getTarget().getId().equals("api_image_role_choose")) {
                if (sourceRoles.getSelectedCount() > 0) {
                    for (Listitem ti : sourceRoles.getSelectedItems()) {
                        RoleVo vo = ti.getValue();
                        targetRoles.appendChild(createRole(vo));
                    }
                }
                setRunAsRoles();
            } else if (evt.getTarget().getId().equals("api_image_role_remove")) {
                if (targetRoles.getSelectedCount() > 0) {
                    List<Component> cs = new ArrayList<Component>();
                    for (Listitem ti : targetRoles.getSelectedItems())
                        cs.add(ti);
                    for (Component c : cs)
                        c.detach();
                }
                setRunAsRoles();
            } else if (evt.getTarget().getId().equals("api_image_role_removeAll")) {
                targetRoles.getItems().clear();
                setRunAsRoles();
            } else if (evt.getTarget().getId().equals("api_image_user_chooseAll")) {
                List<Listitem> items = sourceUsers.getItems();
                for (Listitem ti : items) {
                    UserVo vo = ti.getValue();
                    targetUsers.appendChild(createUser(vo));
                }
                setRunAsUsers();
            } else if (evt.getTarget().getId().equals("api_image_user_choose")) {
                if (sourceUsers.getSelectedCount() > 0) {
                    for (Listitem ti : sourceUsers.getSelectedItems()) {
                        UserVo vo = ti.getValue();
                        targetUsers.appendChild(createUser(vo));
                    }
                }
                setRunAsUsers();
            } else if (evt.getTarget().getId().equals("api_image_user_remove")) {
                if (targetUsers.getSelectedCount() > 0) {
                    List<Component> cs = new ArrayList<Component>();
                    for (Listitem ti : targetUsers.getSelectedItems())
                        cs.add(ti);
                    for (Component c : cs)
                        c.detach();
                }
                setRunAsUsers();
            } else if (evt.getTarget().getId().equals("api_image_user_removeAll")) {
                targetUsers.getItems().clear();
                setRunAsUsers();
            }
            setDirty();
        }
        /*-------------------------------关于授权的----------------------------------*/
    }

    /**
     * 移动栏位
     *
     * @param down
     */
    private void moveInput(boolean down) {
        Listitem item = inputs.getSelectedItem();
        Input input = item.getValue();
        int pos = inputs.getSelectedIndex();
        if (down)
            pos++;
        else
            pos--;
        if (pos < 0)
            pos = 0;
        else if (pos >= inputs.getItemCount())
            pos = inputs.getItemCount() - 1;
        item.detach();
        inputs.getItems().add(pos, item);
        entity.getInputs().remove(input);
        entity.getInputs().add(pos, input);
        setDirty();
    }

    /**
     * 移动栏位
     *
     * @param down
     */
    private void moveOutput(boolean down) {
        Listitem item = outputs.getSelectedItem();
        Output output = item.getValue();
        int pos = outputs.getSelectedIndex();
        if (down)
            pos++;
        else
            pos--;
        if (pos < 0)
            pos = 0;
        else if (pos >= outputs.getItemCount())
            pos = outputs.getItemCount() - 1;
        item.detach();
        outputs.getItems().add(pos, item);
        entity.getOutputs().remove(output);
        entity.getOutputs().add(pos, output);
        setDirty();
    }

    private class InputObject implements EventListener<Event> {

        private Textbox name;

        private Combobox type;

        private Combobox scope;

        private Combobox share;

        private Intbox length;

        private Intbox decimal;

        private Textbox desp;

        private Checkbox notnull;

        private Textbox value;

        private Textbox acc;

        public InputObject(Textbox name, Combobox type, Combobox scope, Combobox share, Intbox length,
                           Intbox decimal, Textbox desp, Checkbox notnull, Textbox value, Textbox acc) {
            this.name = name;
            this.type = type;
            this.scope = scope;
            this.share = share;
            this.length = length;
            this.decimal = decimal;
            this.desp = desp;
            this.notnull = notnull;
            this.value = value;
            this.acc = acc;
            this.name.addEventListener(Events.ON_CHANGE, this);
            this.type.addEventListener(Events.ON_CHANGE, this);
            this.scope.addEventListener(Events.ON_CHANGE, this);
            this.share.addEventListener(Events.ON_CHANGE, this);
            this.length.addEventListener(Events.ON_CHANGE, this);
            this.decimal.addEventListener(Events.ON_CHANGE, this);
            this.desp.addEventListener(Events.ON_CHANGE, this);
            this.notnull.addEventListener(Events.ON_CHECK, this);
            this.value.addEventListener(Events.ON_CHANGE, this);
            this.acc.addEventListener(Events.ON_CHANGE, this);
        }

        @Override
        public void onEvent(Event event) throws Exception {
            Listitem row = (Listitem) name.getParent().getParent();
            Input input = row.getValue();
            if (Events.ON_CHANGE.equals(event.getName())
                    || Events.ON_CHECK.equals(event.getName())) {
                Component c = event.getTarget();
                if (c == name) {
                    String id = name.getValue().trim();
                    input.setName(id);
                } else if (c == type)
                    input.setType(FieldType.getType(type.getSelectedItem()
                            .getLabel()));
                else if (c == scope)
                    input.setScope(ScopeType.getType(scope.getSelectedItem()
                            .getLabel()));
                else if (c == share)
                    input.setShareModel((Integer) share.getSelectedItem().getValue());
                else if (c == length)
                    input.setLength(length.getValue());
                else if (c == decimal)
                    input.setDecimal(decimal.getValue());
                else if (c == desp)
                    input.setDesp(desp.getValue());
                else if (c == notnull)
                    input.setRequired(notnull.isChecked());
                else if (c == value)
                    input.setValue(value.getValue());
                else if (c == acc)
                    input.setAcc(acc.getValue());
                setDirty();
            }
        }
    }

    private class OutputObject implements EventListener<Event> {

        private Textbox name;

        private Textbox desp;

        private Checkbox notnull;


        public OutputObject(Textbox name, Textbox desp, Checkbox notnull) {
            this.name = name;
            this.desp = desp;
            this.notnull = notnull;
            this.name.addEventListener(Events.ON_CHANGE, this);
            this.desp.addEventListener(Events.ON_CHANGE, this);
            this.notnull.addEventListener(Events.ON_CHECK, this);
        }

        @Override
        public void onEvent(Event event) throws Exception {
            Listitem row = (Listitem) name.getParent().getParent();
            Output output = row.getValue();
            if (Events.ON_CHANGE.equals(event.getName())
                    || Events.ON_CHECK.equals(event.getName())) {
                Component c = event.getTarget();
                if (c == name) {
                    String id = name.getValue().trim();
                    output.setName(id);
                } else if (c == desp)
                    output.setDesp(desp.getValue());
                else if (c == notnull)
                    output.setRequired(notnull.isChecked());
                setDirty();
            }
        }
    }
}
